package com.hellomaker.redismq.starter.config;

import com.hellomaker.redismq.consume.GroupConsumer;
import com.hellomaker.redismq.consume.listener.ListenerContainer;
import com.hellomaker.redismq.core.mq.SimpleRedisMQClient;
import com.hellomaker.redismq.starter.config.listener.ListenerMethod;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @author xianzhikun
 * @version 1.0.0
 * @see ListenerAnnotationParser
 */
@Deprecated
public class ListenerBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {

    private List<Method> listenerMethods = new ArrayList<>();

    public List<Method> getListenerMethods() {
        return listenerMethods;
    }

    SimpleRedisMQClient client;
    ApplicationContext applicationContext;
    ListenerContainer<String, String> listenerContainer;

    public void setSimpleClient(SimpleRedisMQClient client) {
        this.client = client;
    }

    void setListenerContainer(ListenerContainer<String, String> container) {
        this.listenerContainer = container;
    }

    public ListenerContainer<String, String> getListenerContainer() {
        if (listenerContainer == null) {
            listenerContainer = new ListenerContainer<>();
        }
        return listenerContainer;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> aClass = bean.getClass();
        if (ListenMessage.class.isAssignableFrom(aClass) && aClass.isAnnotationPresent(MessageListener.class)) {
            try {
                Method onMessageMethod = aClass.getDeclaredMethod("onMessage", GroupConsumer.class, List.class);
                MessageListener messageListener = aClass.getAnnotation(MessageListener.class);
                ListenerMethod listenerMethod = new ListenerMethod(client, getListenerContainer(), messageListener, onMessageMethod, bean);
                listenerMethod.doListen();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            if (declaredMethod.isAnnotationPresent(MessageListener.class)) {
                MessageListener messageListener = declaredMethod.getAnnotation(MessageListener.class);
                ListenerMethod listenerMethod = new ListenerMethod(client, getListenerContainer(), messageListener, declaredMethod, bean);
                listenerMethod.doListen();
            }
        }
        return bean;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
